package pointer

import "fmt"

/** 指针教程 */

// 示例1
func case1() {
	b := 5
	var a *int = &b
	fmt.Printf("a 的类型 %T  a 的值 %v \n", a, *a)
	fmt.Println("a的地址值= ", a)

	// 指针 nil 空值
	a2 := 25
	var b2 *int
	if b2 == nil {
		fmt.Println("b is", b2)
		b2 = &a2
		fmt.Println("b2 = ", b2)
	}

	// 修改指针值, 由于b3 指向a3，所以b3发生改变a3也变
	a3 := 45
	b3 := &a3
	fmt.Printf("a3 = %v \n", a3)
	fmt.Printf("b3 = %v;  获取b3的值 = %v \n", b3, *b3)
	*b3++
	fmt.Printf("a3 = %v; b3 = %v \n", a3, *b3)
	a3++ // a3 发生改变 b3也会变
	fmt.Printf("a3 = %v; b3 = %v \n", a3, *b3)

}

// 示例2 向函数传递指针参数 💀不建议这么用
func case2() {
	a := 58
	b := &a
	change(b)
	fmt.Println(a)
	fmt.Println(*b)
}

func change(val *int) {
	*val = 88
}

// 示例3 不要向函数传递数组的指针，而应该使用切片
func case3() {
	var a [3]int = [3]int{1, 2, 3}
	modify(&a)
	fmt.Println(a)
	modify2(&a)
	fmt.Println(a)

	modify3(a[:])
	fmt.Println(a)
}

func modify(arr *[3]int) {
	(*arr)[0] = 90
}

// 简写形式
func modify2(arr *[3]int) {
	arr[0] = 91
}

// go语言惯用方式，使用切片来处理 👍
func modify3(sls []int) {
	sls[0] = 90
}

func Test() {

	case1()

	case2()

	case3()

}
